﻿using CATLTempUpdate.TcpServer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Timers;

namespace CATLTempUpdate.TcpClient
{
    class ClientRequest
    {
        //定义,最好定义成静态的, 因为我们只需要一个就好  
        SocketManager smanager = null;

        //定义事件与委托  
        public delegate void ReceiveData(byte[] buffMsg);
        public delegate void ServerClosed();
        public event ReceiveData OnReceiveData;
        public event ServerClosed OnServerClosed;

        //<summary>  
        //心跳定时器  
        //</summary>  
        System.Timers.Timer heartTimer = null;
        ///// <summary>  
        ///// 心跳包  
        ///// </summary>  
        //static ApiResponse heartRes = null;

        /// <summary>  
        /// 判断是否已连接  
        /// </summary>  
        public bool Connected
        {
            get { return smanager != null && smanager.Connected; }
        }

        ///// <summary>  
        ///// 已登录的用户信息  
        ///// </summary>  
        //public static UserInfoModel UserInfo
        //{
        //    get { return userInfo; }
        //}


        #region 基本方法

        string IP;
        int PORT;
        /// <summary>  
        /// 连接到服务器  
        /// </summary>  
        /// <returns></returns>  
        public SocketError Connect(string ip, int port)
        {
            this.IP = ip;
            this.PORT = port;
            if (Connected) return SocketError.Success;
            //我这里是读取配置,   
            //string ip = Config.ReadConfigString("socket", "server", "");
            //int port = Config.ReadConfigInt("socket", "port", 13909);
            if (string.IsNullOrWhiteSpace(ip) || port <= 1000) return SocketError.Fault;

            //创建连接对象, 连接到服务器  
            smanager = new SocketManager(ip, port);
            SocketError error = smanager.Connect();
            if (error == SocketError.Success)
            {
                //连接成功后,就注册事件. 最好在成功后再注册.  
                smanager.ServerDataHandler += OnReceivedServerData;
                smanager.ServerStopEvent += OnServerStopEvent;
            }
            else
            {
                StartHeartbeat();
            }

            return error;
        }

        /// <summary>  
        /// 断开连接  
        /// </summary>  
        public void Disconnect()
        {
            try
            {
                smanager.Disconnect();
            }
            catch (Exception) { }
        }


        ///// <summary>  
        ///// 发送请求  
        ///// </summary>  
        ///// <param name="request"></param>  
        ///// <returns></returns>  
        //public static bool Send(ApiResponse request)
        //{
        //    return Send(JsonConvert.SerializeObject(request));
        //}

        ///// <summary>  
        ///// 发送消息  
        ///// </summary>  
        ///// <param name="message">消息实体</param>  
        ///// <returns>True.已发送; False.未发送</returns>  
        //public static bool Send(string message)
        //{
        //    if (!Connected) return false;

        //    byte[] buff = Encoding.UTF8.GetBytes(message);
        //    //加密,根据自己的需要可以考虑把消息加密  
        //    //buff = AESEncrypt.Encrypt(buff, m_aesKey);  
        //    smanager.Send(buff);
        //    return true;
        //}


        /// <summary>  
        /// 发送字节流  
        /// </summary>  
        /// <param name="buff"></param>  
        /// <returns></returns>  
        public bool Send(byte[] buff)
        {
            if (!Connected)
            {
                StartHeartbeat();
                return false;
            }
            smanager.Send(buff);
            return true;
        }

        /// <summary>  
        /// 接收消息  
        /// </summary>  
        /// <param name="buff"></param>  
        private void OnReceivedServerData(byte[] buff)
        {
            //To do something  
            //你要处理的代码,可以实现把buff转化成你具体的对象, 再传给前台  
            if (OnReceiveData != null)
                OnReceiveData(buff);
        }



        /// <summary>  
        /// 服务器已断开  
        /// </summary>  
        private void OnServerStopEvent()
        {
            if (OnServerClosed != null)
                OnServerClosed();
        }

        #endregion

        #region 心跳包
        //心跳包也是很重要的,看自己的需要了, 我只定义出来, 你自己找个地方去调用吧  
        /// <summary>  
        /// 开启心跳  
        /// </summary>  
        private void StartHeartbeat()
        {
            if (heartTimer == null)
            {
                heartTimer = new System.Timers.Timer();
                heartTimer.Elapsed += TimeElapsed;
            }
            if (!heartTimer.Enabled)
            {
                heartTimer.AutoReset = true;     //循环执行  
                heartTimer.Interval = 200; //每500ms执行一次  
                heartTimer.Enabled = true;
                heartTimer.Start();
            }
        }

        /// <summary>  
        /// 定时执行  
        /// </summary>  
        /// <param name="source"></param>  
        /// <param name="e"></param>  
        private void TimeElapsed(object source, ElapsedEventArgs e)
        {
            if (!Connected)
            {
                Connect(IP, PORT);
            }
        }

        #endregion
    }
}
